use std::{fmt, io, collections::HashMap};
use serde::{Serialize, Deserialize};
use thiserror::Error;


#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum EPmInstallStatu {
    NotExist,
    Installed,
    NeedUpdate,
    Error
}
///dpm运行时的错误返回
#[derive(Debug, Error)]
pub enum DpmError {
    #[error("Pkm config already exist")]
    AlreadyInit,
    #[error("Pkm not init yet")]
    NotInitYet,
    #[error("Pkm config in error fmt.")]
    FmtError(#[from]  fmt::Error),
    #[error("File read/write error!")]
    IoError(#[from]  io::Error),
    #[error("Remote api failed!")]
    ApiFailed(String),
    #[error("Donwload pm failed!")]
    DownloadFiled,    
}

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct DpmCell {
    //remote+loc struct
    pub name: String,
    pub ver: String,
    pub license: Option<String>,
    pub descript: Option<String>,
    pub md5: Option<String>,
    pub lan_id: Option<u16>, 
    pub runtime: Option<String>, 
    pub url: Option<String>,
    //loc only
    pub scripts: Option<HashMap<String, String>>
}


///本地配置文件
#[derive(Debug)]
pub struct PkgInfo {
    pub(crate) base: DpmCell,
}

impl PkgInfo {

    ///设置包的md5
    pub fn set_md5(&mut self, md5: Option<String>) {
        self.base.md5 = md5;
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct RespVO<T> {
    pub data: Option<T>,
    pub code: u16,
    pub msg: String,
}

pub fn fname_to_nv(fname: &str) -> (&str, &str) {
    if !fname.contains("@") {
        return (fname, "");
    }
    let li = fname.split("@").collect::<Vec<&str>>();
    return match li.len() {
        1 => {
            (li[0], "*")
        }
        2 => {
            (li[0], li[1])
        }
        _ => {
            ("", "")
        }
    };
}
